﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using ConfigurationSettings;
using ServiceLocator;

namespace CustomControls
{
    internal class FslviDemo : PictureBox
    {

        #region ** Private Member Variables **

        #region ** Colors **

        private Color _mouseOverDateColor1;
        private Color _mouseOverDateColor2;
        private float _mouseOverDateDirection;
        private Color _mouseOverNameColor1;
        private Color _mouseOverNameColor2;
        private float _mouseOverNameDirection;
        private Color _mouseOverSizeColor1;
        private Color _mouseOverSizeColor2;
        private float _mouseOverSizeDirection;
        private Color _plainDateColor1;
        private Color _plainDateColor2;
        private float _plainDateDirection;
        private Color _plainNameColor1;
        private Color _plainNameColor2;
        private float _plainNameDirection;
        private Color _plainSizeColor1;
        private Color _plainSizeColor2;
        private float _plainSizeDirection;
        private Color _selectedDateColor1;
        private Color _selectedDateColor2;
        private float _selectedDateDirection;
        private Color _selectedMouseOverDateColor1;
        private Color _selectedMouseOverDateColor2;
        private float _selectedMouseOverDateDirection;

        private Color _selectedMouseOverNameColor1;
        private Color _selectedMouseOverNameColor2;
        private float _selectedMouseOverNameDirection;
        private Color _selectedMouseOverSizeColor1;
        private Color _selectedMouseOverSizeColor2;
        private float _selectedMouseOverSizeDirection;
        private Color _selectedNameColor1;
        private Color _selectedNameColor2;
        private float _selectedNameDirection;
        private Color _selectedSizeColor1;
        private Color _selectedSizeColor2;
        private float _selectedSizeDirection;

        #endregion

        #region ** Brushes **

        private LinearGradientBrush _plainDateBrush;
        private LinearGradientBrush _plainNameBrush;
        private LinearGradientBrush _plainSizeBrush;

        private SolidBrush _textBrush;

        #endregion

        private Font _currentFont;
        private Rectangle _dateRectangle;
        private Font _mouseOverFont;
        private Color _mouseOverForeColor;
        private Rectangle _nameRectangle;
        private bool _resetBrush = true;
        private bool _selected;
        private Font _selectedFont;
        private Color _selectedForeColor;
        private Font _selectedMouseOverFont;
        private Color _selectedMouseOverForeColor;


        private Rectangle _sizeRectangle;

        #endregion

        #region ** Public Properties **

        #region ** Colors **

        public Color PlainNameColor1
        {
            get { return _plainNameColor1; }
            set
            {
                _plainNameColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color PlainNameColor2
        {
            get { return _plainNameColor2; }
            set
            {
                _plainNameColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float PlainNameDirection
        {
            get { return _plainNameDirection; }
            set
            {
                _plainNameDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color PlainSizeColor1
        {
            get { return _plainSizeColor1; }
            set
            {
                _plainSizeColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color PlainSizeColor2
        {
            get { return _plainSizeColor2; }
            set
            {
                _plainSizeColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float PlainSizeDirection
        {
            get { return _plainSizeDirection; }
            set
            {
                _plainSizeDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color PlainDateColor1
        {
            get { return _plainDateColor1; }
            set
            {
                _plainDateColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color PlainDateColor2
        {
            get { return _plainDateColor2; }
            set
            {
                _plainDateColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float PlainDateDirection
        {
            get { return _plainDateDirection; }
            set
            {
                _plainDateDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color MouseOverNameColor1
        {
            get { return _mouseOverNameColor1; }
            set
            {
                _mouseOverNameColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color MouseOverNameColor2
        {
            get { return _mouseOverNameColor2; }
            set
            {
                _mouseOverNameColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float MouseOverNameDirection
        {
            get { return _mouseOverNameDirection; }
            set
            {
                _mouseOverNameDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color MouseOverSizeColor1
        {
            get { return _mouseOverSizeColor1; }
            set
            {
                _mouseOverSizeColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color MouseOverSizeColor2
        {
            get { return _mouseOverSizeColor2; }
            set
            {
                _mouseOverSizeColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float MouseOverSizeDirection
        {
            get { return _mouseOverSizeDirection; }
            set
            {
                _mouseOverSizeDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color MouseOverDateColor1
        {
            get { return _mouseOverDateColor1; }
            set
            {
                _mouseOverDateColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color MouseOverDateColor2
        {
            get { return _mouseOverDateColor2; }
            set
            {
                _mouseOverDateColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float MouseOverDateDirection
        {
            get { return _mouseOverDateDirection; }
            set
            {
                _mouseOverDateDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedNameColor1
        {
            get { return _selectedNameColor1; }
            set
            {
                _selectedNameColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedNameColor2
        {
            get { return _selectedNameColor2; }
            set
            {
                _selectedNameColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float SelectedNameDirection
        {
            get { return _selectedNameDirection; }
            set
            {
                _selectedNameDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedSizeColor1
        {
            get { return _selectedSizeColor1; }
            set
            {
                _selectedSizeColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedSizeColor2
        {
            get { return _selectedSizeColor2; }
            set
            {
                _selectedSizeColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float SelectedSizeDirection
        {
            get { return _selectedSizeDirection; }
            set
            {
                _selectedSizeDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedDateColor1
        {
            get { return _selectedDateColor1; }
            set
            {
                _selectedDateColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedDateColor2
        {
            get { return _selectedDateColor2; }
            set
            {
                _selectedDateColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float SelectedDateDirection
        {
            get { return _selectedDateDirection; }
            set
            {
                _selectedDateDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedMouseOverNameColor1
        {
            get { return _selectedMouseOverNameColor1; }
            set
            {
                _selectedMouseOverNameColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedMouseOverNameColor2
        {
            get { return _selectedMouseOverNameColor2; }
            set
            {
                _selectedMouseOverNameColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float SelectedMouseOverNameDirection
        {
            get { return _selectedMouseOverNameDirection; }
            set
            {
                _selectedMouseOverNameDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedMouseOverSizeColor1
        {
            get { return _selectedMouseOverSizeColor1; }
            set
            {
                _selectedMouseOverSizeColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedMouseOverSizeColor2
        {
            get { return _selectedMouseOverSizeColor2; }
            set
            {
                _selectedMouseOverSizeColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float SelectedMouseOverSizeDirection
        {
            get { return _selectedMouseOverSizeDirection; }
            set
            {
                _selectedMouseOverSizeDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedMouseOverDateColor1
        {
            get { return _selectedMouseOverDateColor1; }
            set
            {
                _selectedMouseOverDateColor1 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public Color SelectedMouseOverDateColor2
        {
            get { return _selectedMouseOverDateColor2; }
            set
            {
                _selectedMouseOverDateColor2 = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        public float SelectedMouseOverDateDirection
        {
            get { return _selectedMouseOverDateDirection; }
            set
            {
                _selectedMouseOverDateDirection = value;
                _resetBrush = true;
                Invalidate();
            }
        }

        #endregion

        [Browsable(true)]
        public override string Text
        {
            get { return base.Text; }
            set
            {
                base.Text = value;
                Invalidate();
            }
        }

        [Browsable(true)]
        public override Font Font
        {
            get { return base.Font; }
            set
            {
                base.Font = value;
                Invalidate();
            }
        }

        [Browsable(true)]
        public override Color ForeColor
        {
            get { return base.ForeColor; }
            set { base.ForeColor = value; }
        }

        public Font MouseOverFont
        {
            get { return _mouseOverFont; }
            set { _mouseOverFont = value; }
        }

        public Color MouseOverForeColor
        {
            get { return _mouseOverForeColor; }
            set { _mouseOverForeColor = value; }
        }

        public Font SelectedFont
        {
            get { return _selectedFont; }
            set { _selectedFont = value; }
        }

        public Color SelectedForeColor
        {
            get { return _selectedForeColor; }
            set { _selectedForeColor = value; }
        }

        public Font SelectedMouseOverFont
        {
            get { return _selectedMouseOverFont; }
            set { _selectedMouseOverFont = value; }
        }

        public Color SelectedMouseOverForeColor
        {
            get { return _selectedMouseOverForeColor; }
            set { _selectedMouseOverForeColor = value; }
        }

        #endregion

        public FslviDemo()
        {
            if (!DesignMode)
            {
                return;
            }

            IApplicationSettings localSettings = Locator.Resolve<IApplicationSettings>();

            #region ** Colors **

            _plainNameColor1 = localSettings.FileSettings.PlainSettings.NameColors.Color1;
            _plainNameColor2 = localSettings.FileSettings.PlainSettings.NameColors.Color2;
            _plainNameDirection = localSettings.FileSettings.PlainSettings.NameColors.Direction;

            _plainSizeColor1 = localSettings.FileSettings.PlainSettings.SizeColors.Color1;
            _plainSizeColor2 = localSettings.FileSettings.PlainSettings.SizeColors.Color2;
            _plainSizeDirection = localSettings.FileSettings.PlainSettings.SizeColors.Direction;

            _plainDateColor1 = localSettings.FileSettings.PlainSettings.DateColors.Color1;
            _plainDateColor2 = localSettings.FileSettings.PlainSettings.DateColors.Color2;
            _plainDateDirection = localSettings.FileSettings.PlainSettings.DateColors.Direction;

            _mouseOverNameColor1 = localSettings.FileSettings.MouseOverSettings.NameColors.Color1;
            _mouseOverNameColor2 = localSettings.FileSettings.MouseOverSettings.NameColors.Color2;
            _mouseOverNameDirection = localSettings.FileSettings.MouseOverSettings.NameColors.Direction;
            _mouseOverSizeColor1 = localSettings.FileSettings.MouseOverSettings.SizeColors.Color1;
            _mouseOverSizeColor2 = localSettings.FileSettings.MouseOverSettings.SizeColors.Color2;
            _mouseOverSizeDirection = localSettings.FileSettings.MouseOverSettings.SizeColors.Direction;
            _mouseOverDateColor1 = localSettings.FileSettings.MouseOverSettings.DateColors.Color1;
            _mouseOverDateColor2 = localSettings.FileSettings.MouseOverSettings.DateColors.Color2;
            _mouseOverDateDirection = localSettings.FileSettings.MouseOverSettings.DateColors.Direction;

            _selectedNameColor1 = localSettings.FileSettings.SelectedSettings.NameColors.Color1;
            _selectedNameColor2 = localSettings.FileSettings.SelectedSettings.NameColors.Color2;
            _selectedNameDirection = localSettings.FileSettings.SelectedSettings.NameColors.Direction;
            _selectedSizeColor1 = localSettings.FileSettings.SelectedSettings.SizeColors.Color1;
            _selectedSizeColor2 = localSettings.FileSettings.SelectedSettings.SizeColors.Color2;
            _selectedSizeDirection = localSettings.FileSettings.SelectedSettings.SizeColors.Direction;
            _selectedDateColor1 = localSettings.FileSettings.SelectedSettings.DateColors.Color1;
            _selectedDateColor2 = localSettings.FileSettings.SelectedSettings.DateColors.Color2;
            _selectedDateDirection = localSettings.FileSettings.SelectedSettings.DateColors.Direction;

            _selectedMouseOverNameColor1 = localSettings.FileSettings.SelectedMouseOverSettings.NameColors.Color1;
            _selectedMouseOverNameColor2 = localSettings.FileSettings.SelectedMouseOverSettings.NameColors.Color2;
            _selectedMouseOverNameDirection = localSettings.FileSettings.SelectedMouseOverSettings.NameColors.Direction;
            _selectedMouseOverSizeColor1 = localSettings.FileSettings.SelectedMouseOverSettings.SizeColors.Color1;
            _selectedMouseOverSizeColor2 = localSettings.FileSettings.SelectedMouseOverSettings.SizeColors.Color2;
            _selectedMouseOverSizeDirection = localSettings.FileSettings.SelectedMouseOverSettings.SizeColors.Direction;
            _selectedMouseOverDateColor1 = localSettings.FileSettings.SelectedMouseOverSettings.DateColors.Color1;
            _selectedMouseOverDateColor2 = localSettings.FileSettings.SelectedMouseOverSettings.DateColors.Color2;
            _selectedMouseOverDateDirection = localSettings.FileSettings.SelectedMouseOverSettings.DateColors.Direction;

            #endregion
        }

        protected override void OnSizeChanged(EventArgs argEventArgs)
        {
            //Build rectangles
            _nameRectangle = new Rectangle(ClientRectangle.X, ClientRectangle.Y, (ClientRectangle.Width / 3), ClientRectangle.Height);
            _sizeRectangle = new Rectangle(ClientRectangle.X + _nameRectangle.Width, ClientRectangle.Y, (ClientRectangle.Width / 3), ClientRectangle.Height);
            _dateRectangle = new Rectangle(_sizeRectangle.X + _sizeRectangle.Width, ClientRectangle.Y, (ClientRectangle.Width / 3), ClientRectangle.Height);

            base.OnSizeChanged(argEventArgs);
        }

        protected override void OnPaint(PaintEventArgs argPaintArgs)
        {
            //Build Brushes
            if (_resetBrush)
            {
                if (_selected)
                {
                    _plainNameBrush = new LinearGradientBrush(_nameRectangle, _selectedNameColor1, _selectedNameColor2, _selectedNameDirection + .01F);
                    _plainSizeBrush = new LinearGradientBrush(_sizeRectangle, _selectedSizeColor1, _selectedSizeColor2, _selectedSizeDirection + .01F);
                    _plainDateBrush = new LinearGradientBrush(_dateRectangle, _selectedDateColor1, _selectedDateColor2, _selectedDateDirection + .01F);
                    _currentFont = _selectedFont;
                    _textBrush = new SolidBrush(_selectedForeColor);
                }
                else
                {
                    _plainNameBrush = new LinearGradientBrush(_nameRectangle, _plainNameColor1, _plainNameColor2, _plainNameDirection + .01F);
                    _plainSizeBrush = new LinearGradientBrush(_sizeRectangle, _plainSizeColor1, _plainSizeColor2, _plainSizeDirection + .01F);
                    _plainDateBrush = new LinearGradientBrush(_dateRectangle, _plainDateColor1, _plainDateColor2, _plainDateDirection + .01F);
                    _currentFont = base.Font;
                    _textBrush = new SolidBrush(base.ForeColor);
                }
                _resetBrush = false;
            }

            StringFormat sf = new StringFormat
                {
                    Alignment = StringAlignment.Near,
                    Trimming = StringTrimming.EllipsisCharacter,
                    FormatFlags = StringFormatFlags.LineLimit | StringFormatFlags.NoWrap
                };

            //Paint boxes
            argPaintArgs.Graphics.FillRectangle(_plainNameBrush, _nameRectangle);
            argPaintArgs.Graphics.FillRectangle(_plainSizeBrush, _sizeRectangle);
            argPaintArgs.Graphics.FillRectangle(_plainDateBrush, _dateRectangle);

            //Write
            argPaintArgs.Graphics.DrawString(base.Text, _currentFont, _textBrush, _nameRectangle, sf);
            argPaintArgs.Graphics.DrawString(base.Text, _currentFont, _textBrush, _sizeRectangle, sf);
            argPaintArgs.Graphics.DrawString(base.Text, _currentFont, _textBrush, _dateRectangle, sf);
        }

        protected override void OnMouseEnter(EventArgs argMouseArgs)
        {
            if (_selected)
            {
                _plainNameBrush = new LinearGradientBrush(_nameRectangle, _selectedMouseOverNameColor1, _selectedMouseOverNameColor2, _selectedMouseOverNameDirection + .01F);
                _plainSizeBrush = new LinearGradientBrush(_sizeRectangle, _selectedMouseOverSizeColor1, _selectedMouseOverSizeColor2, _selectedMouseOverSizeDirection + .01F);
                _plainDateBrush = new LinearGradientBrush(_dateRectangle, _selectedMouseOverDateColor1, _selectedMouseOverDateColor2, _selectedMouseOverDateDirection + .01F);
                _currentFont = _selectedMouseOverFont;
                _textBrush = new SolidBrush(_selectedMouseOverForeColor);
            }
            else
            {
                _plainNameBrush = new LinearGradientBrush(_nameRectangle, _mouseOverNameColor1, _mouseOverNameColor2, _mouseOverNameDirection + .01F);
                _plainSizeBrush = new LinearGradientBrush(_sizeRectangle, _mouseOverSizeColor1, _mouseOverSizeColor2, _mouseOverSizeDirection + .01F);
                _plainDateBrush = new LinearGradientBrush(_dateRectangle, _mouseOverDateColor1, _mouseOverDateColor2, _mouseOverDateDirection + .01F);
                _currentFont = _mouseOverFont;
                _textBrush = new SolidBrush(_mouseOverForeColor);
            }

            Invalidate();
            base.OnMouseEnter(argMouseArgs);
        }

        protected override void OnMouseLeave(EventArgs argEventArgs)
        {
            if (_selected)
            {
                _plainNameBrush = new LinearGradientBrush(_nameRectangle, _selectedNameColor1, _selectedNameColor2, _selectedNameDirection + .01F);
                _plainSizeBrush = new LinearGradientBrush(_sizeRectangle, _selectedSizeColor1, _selectedSizeColor2, _selectedSizeDirection + .01F);
                _plainDateBrush = new LinearGradientBrush(_dateRectangle, _selectedDateColor1, _selectedDateColor2, _selectedDateDirection + .01F);
                _currentFont = _selectedFont;
                _textBrush = new SolidBrush(_selectedForeColor);
            }
            else
            {
                _plainNameBrush = new LinearGradientBrush(_nameRectangle, _plainNameColor1, _plainNameColor2, _plainNameDirection + .01F);
                _plainSizeBrush = new LinearGradientBrush(_sizeRectangle, _plainSizeColor1, _plainSizeColor2, _plainSizeDirection + .01F);
                _plainDateBrush = new LinearGradientBrush(_dateRectangle, _plainDateColor1, _plainDateColor2, _plainDateDirection + .01F);
                _currentFont = base.Font;
                _textBrush = new SolidBrush(base.ForeColor);
            }

            Invalidate();
            base.OnMouseLeave(argEventArgs);
        }

        protected override void OnClick(EventArgs argEventArgs)
        {
            _selected = !_selected;
            OnMouseEnter(new EventArgs());

            base.OnClick(argEventArgs);
        }
    }
}